<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>语音录制应用 - 管理仪表板</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
    <script>
        // 全局错误处理，防止浏览器扩展冲突
        window.addEventListener('error', function(event) {
            // 检查错误是否来自扩展
            if (event.filename && event.filename.includes('chrome-extension://')) {
                // 阻止错误传播
                event.stopPropagation();
                event.preventDefault();
                console.warn('已拦截来自浏览器扩展的错误:', event.message);
                return true;
            }
        }, true);
        
        // 拦截未处理的Promise错误
        window.addEventListener('unhandledrejection', function(event) {
            // 检查错误是否与消息端口相关
            if (event.reason && event.reason.message && 
                (event.reason.message.includes('message port') || 
                 event.reason.message.includes('port closed'))) {
                // 阻止错误传播
                event.stopPropagation();
                event.preventDefault();
                console.warn('已拦截消息端口错误:', event.reason.message);
                return true;
            }
        });
    </script>
    <style>
        .dashboard {
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
        }
        .card {
            background-color: #fff;
            border-radius: 8px;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
            padding: 20px;
            margin-bottom: 20px;
        }
        .card-header {
            border-bottom: 1px solid #eee;
            padding-bottom: 15px;
            margin-bottom: 15px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .card-title {
            font-size: 1.2rem;
            font-weight: bold;
            margin: 0;
        }
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
            gap: 15px;
        }
        .stat-item {
            background-color: #f9f9f9;
            border-radius: 6px;
            padding: 15px;
            text-align: center;
        }
        .stat-value {
            font-size: 1.8rem;
            font-weight: bold;
            margin: 10px 0;
            color: #2c3e50;
        }
        .stat-label {
            font-size: 0.9rem;
            color: #7f8c8d;
        }
        .progress-bar {
            height: 10px;
            background-color: #ecf0f1;
            border-radius: 5px;
            overflow: hidden;
            margin-top: 10px;
        }
        .progress-fill {
            height: 100%;
            background-color: #3498db;
            border-radius: 5px;
        }
        .actions {
            display: flex;
            gap: 10px;
            margin-top: 20px;
        }
        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-weight: bold;
        }
        .btn-primary {
            background-color: #3498db;
            color: white;
        }
        .btn-danger {
            background-color: #e74c3c;
            color: white;
        }
        .recordings-list {
            margin-top: 20px;
        }
        .recording-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 15px;
            border-bottom: 1px solid #eee;
        }
        .recording-info {
            flex: 1;
        }
        .recording-actions {
            display: flex;
            gap: 10px;
        }
    </style>
</head>
<body>
    <div class="dashboard">
        <h1>语音录制应用 - 管理仪表板</h1>
        
        <div class="card">
            <div class="card-header">
                <h2 class="card-title">存储统计</h2>
                <div class="actions">
                    <button id="refreshStats" class="btn btn-primary">刷新</button>
                    <button id="cleanupStorage" class="btn btn-danger">清理孤立文件</button>
                </div>
            </div>
            
            <div class="stats-grid">
                <div class="stat-item">
                    <div class="stat-label">录音数量</div>
                    <div class="stat-value" id="recordingsCount">{{ storage_stats.recordings_count }}</div>
                </div>
                
                <div class="stat-item">
                    <div class="stat-label">总存储大小</div>
                    <div class="stat-value" id="totalStorage">{{ storage_stats.total_storage_readable }}</div>
                </div>
                
                <div class="stat-item">
                    <div class="stat-label">磁盘总容量</div>
                    <div class="stat-value" id="diskTotal">{{ storage_stats.disk_total_readable }}</div>
                </div>
                
                <div class="stat-item">
                    <div class="stat-label">磁盘已用</div>
                    <div class="stat-value" id="diskUsed">{{ storage_stats.disk_used_readable }}</div>
                </div>
                
                <div class="stat-item">
                    <div class="stat-label">磁盘可用</div>
                    <div class="stat-value" id="diskFree">{{ storage_stats.disk_free_readable }}</div>
                </div>
                
                <div class="stat-item">
                    <div class="stat-label">磁盘使用率</div>
                    <div class="stat-value" id="diskUsagePercent">{{ storage_stats.disk_usage_percent }}%</div>
                    <div class="progress-bar">
                        <div class="progress-fill" style="width: {{ storage_stats.disk_usage_percent }}%"></div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="card">
            <div class="card-header">
                <h2 class="card-title">录音列表</h2>
                <div class="actions">
                    <button id="refreshRecordings" class="btn btn-primary">刷新</button>
                </div>
            </div>
            
            <div class="recordings-list" id="recordingsList">
                <!-- 录音列表将通过JavaScript动态加载 -->
                <p>加载中...</p>
            </div>
        </div>
    </div>
    
    <script>
        // 获取存储统计信息
        function fetchStorageStats() {
            fetch('/api/storage/stats')
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        const stats = data.stats;
                        document.getElementById('recordingsCount').textContent = stats.recordings_count;
                        document.getElementById('totalStorage').textContent = stats.total_storage_readable;
                        document.getElementById('diskTotal').textContent = stats.disk_total_readable;
                        document.getElementById('diskUsed').textContent = stats.disk_used_readable;
                        document.getElementById('diskFree').textContent = stats.disk_free_readable;
                        document.getElementById('diskUsagePercent').textContent = stats.disk_usage_percent + '%';
                        document.querySelector('.progress-fill').style.width = stats.disk_usage_percent + '%';
                    }
                })
                .catch(error => console.error('获取存储统计信息失败:', error));
        }
        
        // 获取录音列表
        function fetchRecordings() {
            fetch('/api/recordings')
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        const recordings = data.recordings;
                        const recordingsList = document.getElementById('recordingsList');
                        
                        if (recordings.length === 0) {
                            recordingsList.innerHTML = '<p>暂无录音</p>';
                            return;
                        }
                        
                        let html = '';
                        recordings.forEach(recording => {
                            html += `
                                <div class="recording-item" data-id="${recording.id}">
                                    <div class="recording-info">
                                        <h3>${recording.original_filename || recording.filename}</h3>
                                        <p>大小: ${formatFileSize(recording.file_size)} | 时长: ${formatDuration(recording.duration)} | 格式: ${recording.format}</p>
                                        <p>上传时间: ${formatDate(recording.created_at)}</p>
                                    </div>
                                    <div class="recording-actions">
                                        <button class="btn btn-primary play-recording" data-id="${recording.id}">播放</button>
                                        <button class="btn btn-danger delete-recording" data-id="${recording.id}">删除</button>
                                    </div>
                                </div>
                            `;
                        });
                        
                        recordingsList.innerHTML = html;
                        
                        // 添加事件监听器
                        document.querySelectorAll('.delete-recording').forEach(button => {
                            button.addEventListener('click', function() {
                                const recordingId = this.getAttribute('data-id');
                                deleteRecording(recordingId);
                            });
                        });
                        
                        document.querySelectorAll('.play-recording').forEach(button => {
                            button.addEventListener('click', function() {
                                const recordingId = this.getAttribute('data-id');
                                playRecording(recordingId);
                            });
                        });
                    }
                })
                .catch(error => console.error('获取录音列表失败:', error));
        }
        
        // 删除录音
        function deleteRecording(recordingId) {
            if (confirm('确定要删除这个录音吗？此操作不可撤销。')) {
                fetch(`/api/recordings/${recordingId}`, {
                    method: 'DELETE'
                })
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        alert('录音已删除');
                        fetchRecordings();
                        fetchStorageStats();
                    } else {
                        alert('删除失败: ' + data.message);
                    }
                })
                .catch(error => console.error('删除录音失败:', error));
            }
        }
        
        // 播放录音
        function playRecording(recordingId) {
            fetch(`/api/recordings/${recordingId}`)
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        const recording = data.recording;
                        const audio = new Audio(`/uploads/${recording.filename}`);
                        audio.play();
                    }
                })
                .catch(error => console.error('获取录音信息失败:', error));
        }
        
        // 清理孤立文件
        function cleanupStorage() {
            if (confirm('确定要清理孤立文件吗？此操作将删除数据库中不存在但文件系统中存在的文件。')) {
                fetch('/api/storage/cleanup', {
                    method: 'POST'
                })
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'success') {
                        const result = data.result;
                        alert(`清理完成: 删除了 ${result.deleted_count} 个文件，共 ${result.deleted_size_readable}`);
                        fetchStorageStats();
                    } else {
                        alert('清理失败: ' + data.message);
                    }
                })
                .catch(error => console.error('清理存储失败:', error));
            }
        }
        
        // 格式化文件大小
        function formatFileSize(bytes) {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
        }
        
        // 格式化时长
        function formatDuration(seconds) {
            const minutes = Math.floor(seconds / 60);
            const remainingSeconds = Math.floor(seconds % 60);
            return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
        }
        
        // 格式化日期
        function formatDate(dateString) {
            const date = new Date(dateString);
            return date.toLocaleString();
        }
        
        // 添加事件监听器
        document.getElementById('refreshStats').addEventListener('click', fetchStorageStats);
        document.getElementById('refreshRecordings').addEventListener('click', fetchRecordings);
        document.getElementById('cleanupStorage').addEventListener('click', cleanupStorage);
        
        // 页面加载时获取数据
        document.addEventListener('DOMContentLoaded', function() {
            fetchStorageStats();
            fetchRecordings();
        });
    </script>
</body>
</html> 